#include "SessionFriendApplyArea.h"
#include <Windows.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <QPainter>
#include <QStyleOption>
#include <QVBoxLayout>
#include "Custom/CircleButton.h"
#include "Debug.h"
#include "Model/DataCenter.h"
#include "MainWidget.h"

using namespace model;
SessionFriendApplyArea::SessionFriendApplyArea(QWidget* parent)
    : QScrollArea(parent)
{
    /* 设置QScrollArea的属性 */
    this->setWidgetResizable(true);  // 自动出现滚动条
    this->setStyleSheet(SCROLL_STYLE);
    /* 创建内部容器 */
    container = new QWidget(this);
    container->setFixedWidth(300);
    this->setWidget(container);
    /* 创建布局 */
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->setAlignment(Qt::AlignTop);  // 向上对齐
    container->setLayout(layout);
#ifdef TEST_UI
    // for (int i = 0; i < 5; ++i) {
    //     QPushButton* btn = new QPushButton();
    //     btn->setText("按钮" + QString::number(i));
    //     // btn->setFixedHeight(50);
    //     layout->addWidget(btn);
    // }
    for (int i = 0; i < 50; ++i) {
        const QIcon   icon(":/image/defaultAvatar.png");
        const QString name     = QString("name") + QString::number(i);
        const QString last_mes = QString("last message...") + QString::number(i);
        add_item(SESSION_TYPE, QString::number(i), icon, name, last_mes);
        // add_item(APPLY_TYPE, QString::number(i), icon, name, last_mes);
    }
#endif
}

/// @brief: 向 container 中添加元素
void SessionFriendApplyArea::add_item(ItemType type, const QString& id, const QIcon& icon,
                                      const QString& name, const QString& last_message)
{
    SessionFriendApplyItem* item = nullptr;
    switch (type) {
    case SESSION_TYPE:
        item = new SessionItem(id, this, icon, name, last_message);
        break;
    case FRIEND_TYPE:
        item = new FriendItem(id, this, icon, name, last_message);
        break;
    case APPLY_TYPE:
        item = new FriendApplyItem(id, this, icon, name);
        break;
    default:
        LOG() << "bad type: " << type;
        break;
    }
    if (item == nullptr) {
        LOG() << "item is nullptr, type: " << type;
    }
    container->layout()->addWidget(item);
}

/// @brief: 清空 container 中的元素
void SessionFriendApplyArea::clear_item()
{
    QLayout* layout = container->layout();
    for (int i = layout->count() - 1; i >= 0; --i) {
        auto child = layout->takeAt(i);
        if (child != nullptr) {
            delete child->widget();  // 删除这个坐标所对应的widget
            delete child;
        }
    }
}

/// @brief 选中 container 指定的 item
/// @return 成功返回 true, 失败返回 false
bool SessionFriendApplyArea::click_item(int index)
{
    LOG() << "click_item" << index;
    QLayout* layout = container->layout();
    int      cnt    = layout->count();
    /* error handing */
    if (index < 0 || index >= cnt) {
        LOG() << "bad index: " << index;
        return false;
    }
    QLayoutItem* item = layout->itemAt(index);
    if (item->widget() == nullptr) {
        LOG() << "there is no such item: " << index;
        return false;
    }
    /* change the qss of the selected item */
    SessionFriendApplyItem* index_item =
        dynamic_cast<SessionFriendApplyItem*>(item->widget());
    if (index_item == nullptr) {
        LOG() << "dynamic cast error";
        return false;
    }
    index_item->check_select();
    return true;
}

SessionFriendApplyItem::SessionFriendApplyItem(QWidget* owner, const QIcon& avatar, const QString& name, const QString& last_message)
    : owner(owner)
{
    /* 设置头像 */
    CircleButton* u_avatar = new CircleButton();

    u_avatar->setIcon(avatar);
    u_avatar->setIconSize(QSize(40, 40));
    u_avatar->setFixedSize(QSize(40, 40));
    u_avatar->setStyleSheet(
        "QPushButton {"
        "border: none;"
        "background-color:#F0F0F0"
        "}");
    /* 设置昵称和最后一条消息消息 */
    QLabel* u_name = new QLabel();
    u_name->setText(name);
    u_name->setStyleSheet(
        "QLabel {"
        "font-size: 18px;"
        "font-weight: 600;"
        "}");
    u_name->setFixedHeight(30);
    u_name->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    u_last_mes = new QLabel();
    u_last_mes->setText(last_message);
    u_last_mes->setFixedHeight(30);
    u_last_mes->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
    /* 设置这个Widget的样式 */
    this->setStyleSheet(
        "QWidget{"
        "background-color: #F5F5F5;"
        "};");
    this->setFixedHeight(60);
    this->is_selected = false;
    /* 添加布局管理器 */
    QGridLayout* layout = new QGridLayout();
    this->setLayout(layout);
    layout->setContentsMargins(10, 0, 0, 0);
    layout->setSpacing(0);
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(0);
    /* 将之前写的部件添加到该布局管理器中 */
    layout->addWidget(u_avatar, 0, 0, 2, 1);    // 占据2行1列
    layout->addWidget(u_name, 0, 1, 1, 4);      // 占据1行4列
    layout->addWidget(u_last_mes, 1, 1, 1, 4);  // 占据1行4列
    /* 获取data_center */
    data_center = DataCenter::get_instance();
}

/// @brief: 代码来自Qt官方文档, 见Qt Style Sheet Reference
void SessionFriendApplyItem::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event);
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);  // 必须这样设置，不然自定义Widget的样式不会显式
}

/// @brief: 处理鼠标点击的事件, 切换背景颜色为#0099FF
void SessionFriendApplyItem::SessionFriendApplyItem::mousePressEvent(QMouseEvent* event)
{
    Q_UNUSED(event);
    check_select();
}

/// @brief: 鼠标进入 item 的事件
void SessionFriendApplyItem::enterEvent(QEnterEvent* event)
{
    Q_UNUSED(event);
    if (is_selected) {
        /* current item is selected, do nothing */
        return;
    }
    this->setStyleSheet(
        "QWidget {"
        "background-color: #E7E7E7}");
}

/// @brief: 鼠标离开 item 的事件
void SessionFriendApplyItem::leaveEvent(QEvent* event)
{
    Q_UNUSED(event);
    if (is_selected) {
        /* current item is selected, do nothing */
        return;
    }
    this->setStyleSheet(
        "QWidget {"
        "background-color: #F5F5F5}");
}

/// @brief: 设置当前 item 为选中状态, 清理其他 item 的样式, 并调用激活函数
void SessionFriendApplyItem::check_select()
{
    //LOG() << "SessionFriendApplyItem check_select";
    const QObjectList& children = this->parentWidget()->children();  // 找到当前widget的parent所有child
    for (QObject* child : std::as_const(children)) {
        if (!child->isWidgetType()) {
            /* 不是Widget类型，跳过 */
            // LOG() << "not widget";
            continue;
        }
        SessionFriendApplyItem* item = dynamic_cast<SessionFriendApplyItem*>(child);  // 转换
        if (item == nullptr) {
            LOG() << "dynamic_cast error";
            continue;
        }
        item->is_selected = false;
        item->setStyleSheet(
            "QWidget {"
            "background-color: #F5F5F5}");
    }
    this->is_selected = true;
    this->setStyleSheet(
        "QWidget {"
        "background-color: #0099FF}");
    /*
     * 在变量在编译期时,
     * this 的静态类型是 SessionFriendApplyItem*（基类指针）,
     * 子类只要重写该虚函数就属于多态调用
     */
    this->active();  // 选中当前item
}

/// @brief 初始化会话信息
SessionItem::SessionItem(const QString& chat_session_id, QWidget* owner, const QIcon& avatar,
                         const QString& name, const QString& last_message)
    : SessionFriendApplyItem(owner, avatar, name, last_message), chat_session_id(chat_session_id), pure_last_msg(last_message)
{
    connect(data_center, &DataCenter::update_last_message, this, &SessionItem::handle_update_last_message, Qt::UniqueConnection);
    /* 构造一下未读消息条数 */
    int unread_count = data_center->get_unread_cnt(chat_session_id);
    //LOG() << "chat_session_id" << chat_session_id << " unread_cnt: " << unread_count;
    if (unread_count > 0) {
        QString text = QString("[未读%1条] %2").arg(unread_count).arg(pure_last_msg);
        u_last_mes->setText(text);
    }
}

/// @brief: 激活当前item调用的函数
void SessionItem::active()
{
    LOG() << "Session Item Active, id: " << chat_session_id;
    MainWidget* main_widget = MainWidget::get_instance();
    main_widget->load_recent_messages(chat_session_id);
    /* 清空这个会话的未读消息数目 */
    data_center->clear_unread_cnt(chat_session_id);
    u_last_mes->setText(pure_last_msg);
}

/// @brief 更新最后一条消息
void SessionItem::handle_update_last_message(const QString& chat_session_id)
{
    /* 不是这个会话, 直接跳过 */
    if (chat_session_id != this->chat_session_id) {
        return;
    }
    /* 获取到最后一条消息 */
    QList<Message>* messages = data_center->get_message_list(chat_session_id);
    if (messages == nullptr || messages->isEmpty()) {
        LOG() << "invalid messages";
        return;
    }
    Message& message = messages->back();
    QString  text;
    switch (message.message_type) {
    case TEXT_TYPE:
        text = message.content;
        break;
    case FILE_TYPE:
        text = "[文件]";
        break;
    case IMAGE_TYPE:
        text = "[图片]";
        break;
    case SPEECH_TYPE:
        text = "[语音]";
        break;
    default:
        text = "[未知]";
        break;
    }
    pure_last_msg = text;
    /* 如果当前会话不是正在选中的会话, 需要更新未读消息数目 */
    if (this->chat_session_id != data_center->get_cur_session_id()) {
        int unread_cnt = data_center->get_unread_cnt(this->chat_session_id);
        text = QString("[未读%1条] %2").arg(unread_cnt).arg(text);
    }
    u_last_mes->setText(text);
}

/// @brief 初始化好友信息
FriendItem::FriendItem(const QString& user_id, QWidget* owner, const QIcon& avatar, const QString& name, const QString& last_message)
    : SessionFriendApplyItem(owner, avatar, name, last_message), user_id(user_id)
{
}

/// @brief 激活该 item 调用的函数
void FriendItem::active()
{
    LOG() << "Friend Item Active, id: " << user_id;
    MainWidget* main_widget = MainWidget::get_instance();
    main_widget->handle_friend_item_active(user_id);
}

FriendApplyItem::FriendApplyItem(const QString& user_id, QWidget* owner, const QIcon& avatar, const QString& name)
    : SessionFriendApplyItem(owner, avatar, name, ""), user_id(user_id)
{
    QLayout*     layout   = this->layout();
    QGridLayout* g_layout = dynamic_cast<QGridLayout*>(layout);
    if (g_layout == nullptr) {
        LOG() << "dynamic cast error";
        return;
    }
    /* 删除 last_message, 添加两个按钮 */
    g_layout->removeWidget(u_last_mes);
    delete u_last_mes;
    ac_btn    = new QPushButton("接受");
    rej_btn   = new QPushButton("忽略");
    QString      btn_style = get_white_button_style() +
                        "QPushButton { border-radius: 2px; }"
                        "QPushButton:hover { border-radius: 2px; }"
                        "QPushButton:pressed { border-radius: 2px; }";
    ac_btn->setStyleSheet(btn_style);
    rej_btn->setStyleSheet(btn_style);
    g_layout->addWidget(ac_btn, 1, 1, 1, 1);
    g_layout->addWidget(rej_btn, 1, 2, 1, 1);
    /* 设置同意和拒绝按钮的信号槽 */
    connect(ac_btn, &QPushButton::clicked, this, [=]() {
        data_center->accept_friend_apply_async(user_id);
    });
    connect(rej_btn, &QPushButton::clicked, this, [=]() {
        data_center->reject_friend_apply_async(user_id);
    });
}

/// @brief 激活该item调用的函数
void FriendApplyItem::active()
{
    LOG() << "Friend Apply Item Active, id: " << user_id;
}